using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.Base.Designer;
using OpenComposite.EII.Designer.SCA;
using System.Xml.Schema;

namespace OpenComposite.EII.Designer.Selector
{
	public partial class FormSelectorConfiguration : Form
	{
		#region Initialization
		public FormSelectorConfiguration(
			Repository.BusinessPolicy policy, List<DesignerControl> listConnectedControls)
		{
			InitializeComponent();

			_policy = policy;
			_listConnectedControls = listConnectedControls;

			init();
		}
		private void init()
		{
			_configdata = new SelectorConfigurationData();
			_selectedItem = null;
			_xsdInput = null;
			_xsdOutput = null;

			cboResultString.Items.Clear();
			foreach ( string item in _policy.PolicyResultStrings ) {
				cboResultString.Items.Add(item);
				listConfig.Groups.Add(item, item);	
			}

			foreach ( DesignerControl dc in _listConnectedControls ) {
				ServiceComponentSymbol scs = dc.Parent as ServiceComponentSymbol;
				if ( scs != null ) {
					cboComponent.Items.Add(new ComponentItem(scs));
				}
			}
		}
		#endregion

		#region Public Members

		#region Properties
		public SelectorConfigurationData ConfigurationData
		{
			get { return null; }
		}
		public string SelectorOperationName
		{
			get { return txtSelectorOperation.Text; }
			set { txtSelectorOperation.Text = value; }
		}
		public XmlSchema SelectorInputSchema
		{
			get { return _xsdInput; }
			set { _xsdInput = value; }
		}
		public XmlSchema SelectorOutputSchema
		{
			get { return _xsdOutput; }
			set { _xsdOutput = value; }
		}
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private Repository.BusinessPolicy _policy;
		private List<DesignerControl> _listConnectedControls;
		private SelectorConfigurationData _configdata;
		private SelectorConfigurationData.SelectorConfigurationItem _selectedItem;
		private XmlSchema _xsdInput;
		private XmlSchema _xsdOutput;
		#endregion

		#region Methods
		private void fillConfigList()
		{
			bool bAlt = false;	// alternate row colors
			Color colAlt = SystemColors.Control;

			listConfig.BeginUpdate();
			listConfig.Items.Clear();
			foreach ( SelectorConfigurationData.SelectorConfigurationItem item in _configdata.Items ) {
				ListViewItem lvi = listConfig.Items.Add(item.PolicyResult);
				lvi.SubItems.Add(item.Component.ToString());
				lvi.SubItems.Add(item.Operation.Name);

				lvi.Group = listConfig.Groups[item.PolicyResult];

				lvi.Tag = item;

				if ( item == _selectedItem ) {
					lvi.Selected = true;
				}

				if ( bAlt )
					lvi.BackColor = colAlt;
				bAlt = !bAlt;
			}
			listConfig.EndUpdate();
		}
		private void displaySelectedItem()
		{
			if ( _selectedItem == null ) {
				cboResultString.SelectedIndex = -1;
				cboComponent.SelectedIndex = -1;
				cboOperation.SelectedIndex = -1;
			} else {
				cboResultString.SelectedItem = _selectedItem.PolicyResult;
				cboComponent.SelectedItem = _selectedItem.Component;
				cboOperation.SelectedItem = _selectedItem.Operation;
			}
		}
		private bool validateItemEntry()
		{
			if ( cboResultString.SelectedIndex == -1 ) {
				MessageBox.Show("Please select a Policy Result String value.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				cboResultString.Focus();
				return false;
			}
			if ( cboComponent.SelectedIndex == -1 ) {
				MessageBox.Show("Please select a component.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				cboComponent.Focus();
				return false;
			}
			if ( cboOperation.SelectedIndex == -1 ) {
				MessageBox.Show("Please select a component operation.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				cboOperation.Focus();
				return false;
			}
			return true;
		}
		private void addnewItem()
		{
			_selectedItem = new SelectorConfigurationData.SelectorConfigurationItem();
			_selectedItem.PolicyResult = cboResultString.SelectedItem as string;
			_selectedItem.Component = cboComponent.SelectedItem as ComponentItem;
			_selectedItem.Operation = cboOperation.SelectedItem as Repository.Operation;
			
			_configdata.Items.Add(_selectedItem);
			fillConfigList();
		}
		private void updateSelectedItem()
		{
			_selectedItem.PolicyResult = cboResultString.SelectedItem as string;
			_selectedItem.Component = cboComponent.SelectedItem as ComponentItem;
			_selectedItem.Operation = cboOperation.SelectedItem as Repository.Operation;
			fillConfigList();
		}
		private void doMapping()
		{
		}
		#endregion

		#region Event Handler
		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.Cancel;
			this.Close();
		}

		private void listConfig_SelectedIndexChanged(object sender, EventArgs e)
		{
			btnChange.Enabled = ( listConfig.SelectedItems.Count > 0 );
			btnRemove.Enabled = ( listConfig.SelectedItems.Count > 0 );
			_selectedItem = null;
			if ( listConfig.SelectedItems.Count > 0 ) {
				_selectedItem = listConfig.SelectedItems[0].Tag as SelectorConfigurationData.SelectorConfigurationItem;
			}
			displaySelectedItem();
		}

		private void btnRemove_Click(object sender, EventArgs e)
		{
			if ( _configdata.Items.Contains(_selectedItem) ) {
				_configdata.Items.Remove(_selectedItem);
				fillConfigList();
			}
		}

		private void cboComponent_SelectedIndexChanged(object sender, EventArgs e)
		{
			cboOperation.BeginUpdate();
			cboOperation.Items.Clear();
			if ( cboComponent.SelectedIndex >= 0 ) {
				ComponentItem item = cboComponent.SelectedItem as ComponentItem;
				if ( item != null ) {
					List<Repository.Operation> list = item.GetOperations();
					foreach ( Repository.Operation op in list ) {
						cboOperation.Items.Add(op);
					}
				}
			}
			cboOperation.EndUpdate();
		}

		private void btnChange_Click(object sender, EventArgs e)
		{
			if ( validateItemEntry() )
				updateSelectedItem();
		}

		private void btnAddNew_Click(object sender, EventArgs e)
		{
			if ( validateItemEntry() )
				addnewItem();
		}

		#endregion

		private void btnMapping_Click(object sender, EventArgs e)
		{
			doMapping();
		}

		#endregion

	}
	#region Class: ComponentItem
	public class ComponentItem
	{
		public ComponentItem(ServiceComponentSymbol component)
		{
			_component = component;
		}

		private ServiceComponentSymbol _component;
		public ServiceComponentSymbol Component
		{
			get { return _component; }
		}

		public List<Repository.Operation> GetOperations()
		{
			List<Repository.Operation> ops = new List<OpenComposite.EII.Repository.Operation>();
			if ( _component != null ) {
				foreach ( InterfaceSymbol isymbol in _component.Interfaces ) {
					ops.AddRange(isymbol.Operations);
				}
			}
			return ops;
		}


		public override string ToString()
		{
			return _component.Name;
		}
	}
	#endregion

	#region Class: SelectorConfigurationData
	public class SelectorConfigurationData
	{
		public SelectorConfigurationData()
		{
			_listItems = new List<SelectorConfigurationItem>();
		}

		private List<SelectorConfigurationItem> _listItems;
		public List<SelectorConfigurationItem> Items
		{
			get { return _listItems; }
			set { _listItems = value; }
		}

		public class SelectorConfigurationItem
		{
			public SelectorConfigurationItem()
			{
				_policyResult = "";
				_component = null;
				_operation = null;
			}

			private string _policyResult;
			public string PolicyResult
			{
				get { return _policyResult; }
				set { _policyResult = value; }
			}
			private ComponentItem _component;
			public ComponentItem Component
			{
				get { return _component; }
				set { _component = value; }
			}
			private Repository.Operation _operation;
			public Repository.Operation Operation
			{
				get { return _operation; }
				set { _operation = value; }
			}
		}
	}
	#endregion
}
